<script setup lang="ts">
import { nextTick, ref, toRaw, type Ref } from 'vue'
import axios from 'axios'
import $ from 'jquery'

import ctrlsql from '../../utils/ControlSql'
import readsql from '../../utils/ReadSql'

import InputPanel from './InputPanel.vue';
import DetailPanel from './DetailPanel.vue'

const localProps = defineProps({
  // be careful: the label must equal to key-name of data
  title: {
    type: String,
    default: ''
  },
  table_name: {
    type: String,
    default: '/api/sql-deal'
  },
  table_labels: {
    type: Array,
    default: []
  },
  table_display_names: {
    type: Array,
    default: []
  },
  table_data: {
    type: Array,
    default: []
  },
  table_data_format: {
    type: Array<Array<string>>,
    default: []
  },
  ctrl_btn: {
    type: Array<string>,
    default: []
  },
  ctrl_url: {
    type: Object,
    default: new Map(),
  },
  edit_options: {
    type: Object,
    default: {}
  },
  detail_labels: {
    type: Array<string>,
    default: []
  },
  detail_label_options: {
    type: Map<string, string>,
    default: new Map()
  },
  detail_display_names: {
    type: Array<string>,
    default: []
  }
})

const waitProcessedColumnSet: Set<string> = new Set()
const waitProcessingColumnMap: Map<string, string> = new Map()
for (var idx = 0; idx < localProps.table_data_format.length; idx += 1) {
  waitProcessedColumnSet.add(localProps.table_data_format[idx][0])
  waitProcessingColumnMap.set(localProps.table_data_format[idx][0], localProps.table_data_format[idx][1])
}

const flushedTable = ref(0)
const deleteModel = ref(false)
const deleteOk = ref(false)
const editModel = ref(false)
const editConfirmStyle = ref('primary')
const detailModel = ref(false)
const displayListRef: Ref<Array<string>> = ref([])
let EDITID: number | undefined = undefined

const inputListRef: Ref<string[]> = ref([])
for (var idx = 0; idx < localProps.edit_options.editListLabels.length; idx += 1) {
  inputListRef.value.push('')
}

const traverseList = (row: any, column: any) => {
  let col_name = column.property
  if (waitProcessedColumnSet.has(col_name)) {
    switch (waitProcessingColumnMap.get(col_name)) {
      case 'is_ornot':
        return row[col_name] == 0 ? '是' : '否'
      case 'obj_msg':
        return row[col_name] ? row[col_name] : '空信息'
      default:
        return row[col_name]
    }
  }
  return row[col_name]
}

const DeleteRow = (base_url: string, table_name: string, id: number) => {
  axios({
    method: 'delete',
    url: base_url,
    params: {
      table: table_name,
      id: id
    }
  }).then((res) => {
    if (res['data']['ok']) {
      deleteOk.value = true
    } else {
      deleteOk.value = false
    }
    deleteModel.value = true
  })
}

const closeDeleteModel = () => {
  if (deleteOk.value) nextTick(() => {
    // flushedTable.value += 1
    location.reload()
  })
  deleteModel.value = false
}

const RestrictRow = (base_url: string, table_name: string, id: number, restricted_status: boolean) => {
  axios({
    url: base_url,
    method: restricted_status ? 'get' : 'delete',
    params: {
      id: id,
      table: localProps.table_name
    }
  }).then((res) => {
    if (res['data']['ok']) location.reload()
    else alert('数据处理层出错，联系技术人员')
  })
}

const openEditModel = (id: number) => {
  EDITID = id
  editModel.value = true
}

const editToSQL = () => {
  if (EDITID == undefined) return

  ctrlsql.ctrlSQL({
    method: 'update',
    table: localProps.table_name,
    keys: localProps.edit_options.editListLabels,
    key_types: localProps.edit_options.editKeyTypes,
    values: inputListRef.value,
    where: [`id=${EDITID}`],
    where_key: 'and',
    group_by_keys: null,
    order_by_keys: null,
    limit: null,
  }).then((res) => {
    if (res['data']['ok']) {
      setTimeout(() => {
        editConfirmStyle.value = 'success'
        $('#edit-confirm').text('添加成功')
        editModel.value = false
      }, 3000)
    } else {
      editConfirmStyle.value = 'danger'
      $('#add-confirm').text('添加失败，数据处理层错误')
    }
    // localProps.edit_options.inputListLabels[2] = 'permission'
    EDITID = undefined
    nextTick(() => { location.reload() })
  })
  editModel.value = false
}

const openDetailModel = (row: any, column: any, event: any) => {
  // console.log( toRaw(column).label ) get the column label
  // console.log(event.property)
  if (toRaw(column).label === '操作') return
  const id = row.id
  let key_types: Array<string> = []
  for (var idx = 0; idx < localProps.detail_labels.length; idx += 1)
    key_types.push('all_type')
  readsql.readSQL({
    table: localProps.table_name,
    keys: localProps.detail_labels,
    key_types: key_types,
    where: [`id=${id}`],
    where_key: 'and',
    group_by_keys: null,
    order_by_keys: null,
    limit: null,
  }).then((res) => {
    if (res['data']['ok']) {
      var target_data = res['data']['data'][0]
      for (var idx = 0; idx < localProps.detail_labels.length; idx += 1) {
        var next_data = target_data[localProps.detail_labels[idx]]
        var option = localProps.detail_label_options.get(localProps.detail_labels[idx])
        if (option != undefined) {
          var data
          switch (option) {
            case 'is_ornot':
              data = target_data[localProps.detail_labels[idx]] == 0 ? '是' : '否'
              displayListRef.value.push(data)
              break
            case 'obj_msg':
              data = target_data[localProps.detail_labels[idx]] == '' ? '空信息' : target_data[localProps.detail_labels[idx]]
              displayListRef.value.push(data)
              break
            default:
              displayListRef.value.push(target_data[localProps.detail_labels[idx]])
          }
        } else {
          displayListRef.value.push(target_data[localProps.detail_labels[idx]])
        }
      }
      detailModel.value = true
    } else {
      alert('数据库处理层出错，联系技术人员')
    }
  })
}
</script>

<template>
  <div class="block_">
    <!-- example (admins) -->
    <!-- <el-table stripe style="width: 100%">
                    <el-table-column label="UId"/>
                    <el-table-column label="UName"/>
                    <el-table-column label="UPermissions"/>
                    <el-table-column>
                      <el-button link type="primary">delete</el-button>
                      <el-button link type="primary">edit</el-button>
                      <el-button link type="primary">restrict</el-button>
                    </el-table-column>
                  </el-table> -->
    <el-table :data="table_data" stripe style="width: 100%" row-key="id" :key="flushedTable" @row-click="openDetailModel">
      <el-table-column v-for="(label, index) in table_labels" :label="table_display_names[index]" :prop="label"
        :formatter="traverseList" />
      <el-table-column label="操作">
        <template v-slot="scope">
          <el-button link v-if="ctrl_btn.findIndex((e) => { return e == 'delete' }) != -1" type="primary"
            @click="DeleteRow(ctrl_url.base, table_name, scope.row.id)">删除</el-button>
          <el-button link v-if="ctrl_btn.findIndex((e) => { return e == 'edit' }) != -1" type="primary"
            @click="openEditModel(scope.row.id)">修改</el-button>
          <el-button link v-if="ctrl_btn.findIndex((e) => { return e == 'restricted' }) != -1" type="primary"
            @click="RestrictRow(ctrl_url.restrict, table_name, scope.row.id, scope.row.restricted == 1)">限制/解除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <el-dialog v-model="deleteModel" title="tips" width="60%">
    <el-alert v-if="deleteOk" title="删除成功" type="success" :closable="false" effect="dark" />
    <el-alert v-else title="删除失败" type="success" :closable="false" effect="dark" />
    <template #footer>
      <span class="model-footer">
        <el-button @click="closeDeleteModel">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="editModel" :title="'修改' + title + '信息'" width="40%">
    <InputPanel :input-list-labels="edit_options.editListLabels" :input-list-types="edit_options.editListTypes"
      :input-list-ref="inputListRef" :input-list-options="edit_options.editListOptions" />
    <template #footer>
      <span class="model-footer">
        <el-button @click="editModel = false">取消</el-button>
        <el-button @click="editToSQL()" :type="editConfirmStyle" id="edit-confirm">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="detailModel" :title="'查看' + title + '信息'" width="40%">
    <DetailPanel :display-list-labels="detail_labels" :display-list-ref="displayListRef"
      :display-label-other-names="detail_display_names" />
    <template #footer>
      <span class="model-footer">
        <el-button @click="detailModel = false">关闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.block_ {
  width: 100%;
}
</style>